package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.BindTeachplanMediaDto;
import com.xuecheng.commons.model.dto.TeachplanDto;
import com.xuecheng.commons.model.vo.MediaVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.domain.TeachplanMedia;
import com.xuecheng.content.mappers.TeachplanMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.TeachplanMediaService;
import com.xuecheng.content.service.TeachplanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.media.api.MediaClient;
import com.xuecheng.web.exceptions.BusinessException;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-09-17
 */
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {
    //课程计划列表-树形结构
    @Override
    public ResponseResult<TeachplanVo> treeNodes(Long courseId) {
        //1.根据courseId查询所有课程数据（包括1、2、3级）
        List<TeachplanVo> teachplanVos = this.baseMapper.treeNodes(courseId);
        //2.筛选1级大纲
        TeachplanVo teachplanVo = teachplanVos.stream().filter(vo -> vo.getGrade() == 1).findFirst().get();
        //3.筛选2级大纲，将2级大纲设置到1级大纲
        List<TeachplanVo> twos = teachplanVos.stream().filter(vo -> vo.getGrade() == 2).collect(Collectors.toList());
        teachplanVo.setTeachPlanTreeNodes(twos);
        //4.筛选3级大纲，将3级大纲设置到2级大纲
        for (TeachplanVo two : twos) {
            List<TeachplanVo> threes = teachplanVos.stream()
                    .filter(vo -> vo.getGrade() == 3 && vo.getParentid().equals(two.getId()))
                    .collect(Collectors.toList());
            two.setTeachPlanTreeNodes(threes);
        }
        return ResponseResult.okResult(teachplanVo);
    }
    @Autowired
    private CourseBaseService courseBaseService;
    //保存或者更新课程计划
    @Override
    public ResponseResult saveOrUpdate(TeachplanDto dto) {
        //1.根据courseId查询课程状态
        CourseBase courseBase = courseBaseService.getById(dto.getCourseId());
        //2.判断课程状态是否可以修改
        if (courseBase==null&&courseBase.getAuditStatus().equals(CourseConstants.AUDIT_COMMIT_STATUS)
                || courseBase.getAuditStatus().equals(CourseConstants.AUDIT_PASTED_STATUS)
                || courseBase.getAuditStatus().equals(CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        //3.处理parentId为空（保存2级大纲时），查询1级大纲
        if (dto.getParentid() == null) {
            LambdaQueryWrapper<Teachplan> w = new LambdaQueryWrapper<>();
            w.eq(Teachplan::getGrade, 1);
            w.eq(Teachplan::getCourseId,dto.getCourseId());
            Teachplan one = this.getOne(w);
            dto.setParentid(one.getId());
        }
        //补充：修复课程数量,查询所有本课程下的三级章节，求总数并加到PlanNum
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getCourseId,dto.getCourseId());
        wrapper.eq(Teachplan::getGrade,3);
        List<Teachplan> list = this.list(wrapper);
        if (list!=null) {
            courseBase.setPlanNum(courseBase.getPlanNum()+list.size());
            this.courseBaseService.updateById(courseBase);
        }
        //4.保存或更新
        Teachplan teachplan = BeanHelper.copyProperties(dto, Teachplan.class);
        //提前设置一个操作成功与否的标志
        Boolean flag=false;
        if (teachplan.getId() == null) {
            //4.1 id不存在时，保存
            flag = this.save(teachplan);
        } else {
            //4.2 id存在时更新
            flag=this.updateById(teachplan);
        }
        //操作不成功时抛异常
        if (!flag) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult();
    }
    //根据id删除课程计划
    @Override
    public ResponseResult deleteById(Long id) {
        //1.根据id查询课程状态
        Teachplan teachplan = this.getById(id);
        CourseBase courseBase = courseBaseService.getById(teachplan.getCourseId());
        if (courseBase == null) {
            throw  new BusinessException(ErrorCode.NOTFOUND);
        }
        String auditStatus = courseBase.getAuditStatus();
        //2.对于审核状态为：已提交，已发布，已审核的课程。抛出自定义业务异常
        if (auditStatus.equals(CourseConstants.AUDIT_COMMIT_STATUS) ||
                auditStatus.equals(CourseConstants.AUDIT_PASTED_STATUS) ||
                auditStatus.equals(CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //3.判断Grade：为3时，课程表中的PlanNum-1
        if (teachplan.getGrade() == 3) {
            courseBase.setPlanNum(courseBase.getPlanNum()-1);
            this.courseBaseService.updateById(courseBase);
        }
        //4.逻辑删除
        boolean remove = this.removeById(id);
        if (!remove) {
            throw  new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult(null);
    }
    @Autowired
    private MediaClient mediaClient;
    @Autowired
    private TeachplanMediaService teachplanMediaService;
    //课程计划绑定媒资
    @Override
    public ResponseResult associateMedia(BindTeachplanMediaDto dto) {
        //1.根据teachplanId查询课程计划，进一步查询所属课程审核状态
        Teachplan teachplan = this.getById(dto.getTeachplanId());
        CourseBase courseBase = courseBaseService.getById(teachplan.getCourseId());
        //获取课程状态
        String auditStatus = courseBase.getAuditStatus();
        if (CourseConstants.AUDIT_COMMIT_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_PASTED_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_PUBLISHED_STATUS.equals(auditStatus)) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //2.调用feign接口查询媒资
        ResponseResult<MediaVo> result = mediaClient.findById(dto.getMediaId());
        MediaVo mediaVo = result.getData();
        //3.查询当前课程计划所绑定的媒资数据
        LambdaQueryWrapper<TeachplanMedia> w = new LambdaQueryWrapper<>();
        w.eq(TeachplanMedia::getTeachplanId,dto.getTeachplanId());
        TeachplanMedia teachplanMedia = teachplanMediaService.getOne(w);
        Boolean flag=false;
        //不存在绑定了的媒资就保存
        if (teachplanMedia == null) {
            teachplanMedia = new TeachplanMedia();
            teachplanMedia.setMediaFilename(mediaVo.getFilename());
            teachplanMedia.setMediaId(dto.getMediaId());
            teachplanMedia.setCourseId(teachplan.getCourseId());
            teachplanMedia.setTeachplanId(dto.getTeachplanId());
            teachplanMedia.setCreateDate(new Date());
            flag=teachplanMediaService.save(teachplanMedia);
        } else {//已经存在绑定的媒资就更新
            teachplanMedia.setMediaId(dto.getMediaId());
            teachplanMedia.setMediaFilename(mediaVo.getFilename());
            flag=teachplanMediaService.updateById(teachplanMedia);
        }
        if (!flag) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        return ResponseResult.okResult();
    }
}
